package demo.ui;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

public class TestAdaBoostFrame extends JFrame{
	
	private JButton btnStartTrain;
	TestCanvas testCanvas;
	private JMenuBar menuBar;
	
	public TestAdaBoostFrame(){
		super("Test AdaBoost");
		setBounds(5, 5, 800, 600);
		initComponents();
		
		addWindowListener(new WindowAdapter() {
			public void windowClosed(WindowEvent ev){
				super.windowClosed(ev);
				
			}
			
			public void windowClosing(WindowEvent ev){
				System.exit(0);
			}
		});
	}
	
	
	private void initComponents(){
		Container c = getContentPane();
		c.setLayout(new BorderLayout());
		
		testCanvas = new TestCanvas();
		
		c.add(testCanvas, BorderLayout.CENTER);
	}
}

class TestCanvas extends Canvas implements MouseListener,
	ComponentListener, MouseMotionListener, AncestorListener {
	
	private Image buffer, backImg;
	private Graphics offScreenGraphic;
	Color bgcolor = new Color(255,233,244);
	Coordinator coordinator;
	
	JPopupMenu contextMenu;
	JMenuItem mniBlue, mniRed;
	
	//data
	ArrayList<SampleObject> _sampleObjects = new ArrayList<SampleObject>();
	SampleObject selectedObject = null;
	
	public TestCanvas(){
		contextMenu = new JPopupMenu();
		mniBlue = new JMenuItem("Blue");
		mniRed = new JMenuItem("Red");
		
		contextMenu.add(mniBlue);
		contextMenu.add(mniRed);
		
		coordinator = new Coordinator(400, 600, 20, 20);
		coordinator.setViewPort(10, 10, 800, 700);
		
		addComponentListener(this);
		addMouseListener(this);
		addMouseMotionListener(this);
		
		
	}
	
	public void finalize(){
		try {
			if(offScreenGraphic != null){
				offScreenGraphic.dispose();
				offScreenGraphic = null;
				buffer.flush();
				backImg.flush();
				buffer = null;
				backImg = null;
			}
			super.finalize();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void paint(Graphics g){
		//clear background
		offScreenGraphic.drawImage(backImg, 0, 0, this);
		//coordinator.draw(offScreenGraphic);
		offScreenGraphic.fillOval(x-15, y-15, 30, 30);
		g.drawImage(buffer, 0, 0, this);
		
		//g.drawImage(backImg, 0, 0, this);
		//g.fillOval(x-15, y-15, 30, 30);
	}
	
	public void update(Graphics g){
		paint(g);
	}

	@Override
	public void mouseClicked(MouseEvent ev) {
		// TODO Auto-generated method stub
		if(ev.getButton()==MouseEvent.BUTTON3){
			contextMenu.show(ev.getComponent(), ev.getX(), ev.getY());
		}
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void componentHidden(ComponentEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void componentMoved(ComponentEvent e) {
		
	}

	@Override
	public void componentResized(ComponentEvent ev) {
		int w = ev.getComponent().getWidth();
		int h = ev.getComponent().getHeight();
		if(offScreenGraphic != null){
			offScreenGraphic.dispose();
			buffer.flush();
			backImg.flush();
			
			buffer = null;
			offScreenGraphic = null;
			backImg = null;
		}
		
		if(w<=0 || w<=0)
			return;
		
		backImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
		Graphics g = backImg.getGraphics();
		g.setColor(bgcolor);
		g.fillRect(0, 0, w, h);
		g.dispose();
		g = null;
		
		buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
		offScreenGraphic = buffer.getGraphics();
		offScreenGraphic.setColor(new Color(255, 19, 4));
	}

	@Override
	public void componentShown(ComponentEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Show hang");
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	int x, y;
	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		// TODO Auto-generated method stub
		x = e.getX();
		y = e.getY();
		repaint();
	}

	@Override
	public void ancestorAdded(AncestorEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void ancestorMoved(AncestorEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void ancestorRemoved(AncestorEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}

class SampleObject{
	float x, y;
	ObjectClass _class;
	
	public void draw(Graphics g){
		
	}
}

enum ObjectClass {
	Red, Blue
}

class Coordinator {
	private int scaleX, scaleY;
	
	//viewport
	private int left, top, right, bottom;
	
	// 0-position
    private int screenX,screenY;
    private Color color, viewPortColor;
        
    public Coordinator(int sx, int sy, int scx, int scy) {
    	scaleX = scx;
        scaleY = scy;
        screenX = sx;
        screenY = sy;
        
        color = new Color(200, 39, 121);
        viewPortColor = new Color(20, 3, 221);
    }
    
    public void onViewChanged(){
    	
    }
        
    public int getScaleX(){
    	return scaleX;
    }
     
    public void setScaleX(int v){
    	scaleX = v;
    }
        
    public int getScaleY() {
    	return scaleY;
    }
       
    public void setScaleY(int v) {
    	scaleY = v;
    }
        
    public int getScreenX(){
    	return screenX;
    }
        
    public void setScreenX(int v){
    	screenX = v;
    }
        
    public int getScreenY(){
    	return screenY;
    }
        
    public void setScreenY(int v){
    	screenY = v;
    }
    
    public void setViewPort(int l, int t, int r, int b){
    	left = l;
    	top = t;
    	right = r;
    	bottom = b;
    }
        
    public void rotate(float a, float x, float y){
    }
        
    public Point world2Screen(float x, float y) {
    	float xs = x * scaleX + screenX;
    	float ys = screenY - (y * scaleY);
        return (new Point( (int)Math.round(xs), (int)Math.round(ys)));
    }
        
        
    public Point world2Screen(float[] p) {
        float xs = p[0] * scaleX + screenX;
        float ys = screenY - (p[1] * scaleY);
        
        return (new Point( (int)Math.round(xs), (int)Math.round(ys)));
    }
        
    public float[] screen2World(int x, int y){
    	float[] result = new float[2];
        result[0] = (screenX + x)/scaleX;
        result[1] = (screenY - y)/scaleY;
        return result;
    }
        
    public float[] screen2World(Point p) {
    	float[] result = new float[3];
        result[0] = (screenX + p.x)/scaleX;
        result[1] = (screenY - p.y)/scaleY;
        return result;
    }
    
    public Point getConner(){
    	return (new Point(screenX, screenY));
    }
    
    public void draw(Graphics g){
    	
    	g.setColor(viewPortColor);
    	g.drawLine(left, top, left, bottom);
    	g.drawLine(left+1, bottom, right, bottom);
    	g.drawLine(right, bottom-1, right, top);
    	g.drawLine(right-1, top, left+1, top);
    	
    	g.setColor(color);
    	if(screenX >= left){
    		if(screenX <= right){
    			//draw the y-axis from top down to bottom
    			g.drawLine(screenX, top, screenX, bottom);
    		}
    	}
    	
    	if(screenY >= top){
    		if(screenY <= bottom){
    			g.drawLine(left, screenY, right, screenY);
    		}
    	}
    }
}